
#include "GameInput.h"

char	CGameInput::m_joyname[80];				// name of joystick
//
BOOL CALLBACK DInput_Enum_Joysticks(LPCDIDEVICEINSTANCE lpddi,
									LPVOID guid_ptr) 
{
	// this function enumerates the joysticks, but
	// stops at the first one and returns the
	// instance guid of it, so we can create it

	*(GUID*)guid_ptr = lpddi->guidInstance; 

	// copy name into global
	strcpy(CGameInput::m_joyname, (char *)lpddi->tszProductName);

	// stop enumeration after one iteration
	return(DIENUM_STOP);

} // end DInput_Enum_Joysticks
//



CGameInput::CGameInput()
{
	m_lpdi			= NULL;					// dinput object
	m_lpdikey		= NULL;					// dinput keyboard
	m_lpdimouse		= NULL;					// dinput mouse
	m_lpdijoy		= NULL;					// dinput joystick

	memset((void*)m_keyboard_state, 0, sizeof(m_keyboard_state));	// contains keyboard state table
	memset((void*)&m_mouse_state, 0, sizeof(m_mouse_state));		// contains state of mouse
	memset((void*)&m_joy_state, 0, sizeof(m_joy_state));			// contains state of joystick

	m_joystick_found = 0;
}

CGameInput::~CGameInput()
{
	Shutdown();
}

int CGameInput::Init(HINSTANCE hInst, HWND hWnd)
{
	// this function initializes directinput

	if (FAILED(DirectInput8Create(hInst, DIRECTINPUT_VERSION, IID_IDirectInput8, (void **)&m_lpdi,NULL)))
		return -1;

	// return success

	m_hWnd			= hWnd;

	return 0;

} // end DInput_Init

int CGameInput::Init_Keyboard()
{
	// this function initializes the keyboard device

	// create the keyboard device  
	if (m_lpdi->CreateDevice(GUID_SysKeyboard, &m_lpdikey, NULL) != DI_OK)
		return -1;

	// set cooperation level
	if (m_lpdikey->SetCooperativeLevel(m_hWnd, 
		DISCL_NONEXCLUSIVE | DISCL_BACKGROUND) != DI_OK)
		return -1;

	// set data format
	if (m_lpdikey->SetDataFormat(&c_dfDIKeyboard) != DI_OK)
		return -1;

	// acquire the keyboard
	if (m_lpdikey->Acquire() != DI_OK)
		return -1;

	// return success
	return 0;

} // end DInput_Init_Keyboard

int CGameInput::Init_Joystick(int min_x, int max_x, int min_y, int max_y, int dead_zone)
{
	// this function initializes the joystick, it allows you to set
	// the minimum and maximum x-y ranges 

	// first find the fucking GUID of your particular joystick
	m_lpdi->EnumDevices(DI8DEVCLASS_GAMECTRL, 
		DInput_Enum_Joysticks, 
		&m_joystickGUID, 
		DIEDFL_ATTACHEDONLY); 

	// create a temporary IDIRECTINPUTDEVICE (1.0) interface, so we query for 2
	LPDIRECTINPUTDEVICE lpdijoy_temp = NULL;

	if (m_lpdi->CreateDevice(m_joystickGUID, &m_lpdijoy, NULL)!=DI_OK)
		return -1;

	// set cooperation level
	if (m_lpdijoy->SetCooperativeLevel(m_hWnd, 
		DISCL_NONEXCLUSIVE | DISCL_BACKGROUND)!=DI_OK)
		return -1;

	// set data format
	if (m_lpdijoy->SetDataFormat(&c_dfDIJoystick)!=DI_OK)
		return -1;

	// set the range of the joystick
	DIPROPRANGE joy_axis_range;

	// first x axis
	joy_axis_range.lMin = min_x;
	joy_axis_range.lMax = max_x;

	joy_axis_range.diph.dwSize       = sizeof(DIPROPRANGE); 
	joy_axis_range.diph.dwHeaderSize = sizeof(DIPROPHEADER); 
	joy_axis_range.diph.dwObj        = DIJOFS_X;
	joy_axis_range.diph.dwHow        = DIPH_BYOFFSET;

	m_lpdijoy->SetProperty(DIPROP_RANGE,&joy_axis_range.diph);

	// now y-axis
	joy_axis_range.lMin = min_y;
	joy_axis_range.lMax = max_y;

	joy_axis_range.diph.dwSize       = sizeof(DIPROPRANGE); 
	joy_axis_range.diph.dwHeaderSize = sizeof(DIPROPHEADER); 
	joy_axis_range.diph.dwObj        = DIJOFS_Y;
	joy_axis_range.diph.dwHow        = DIPH_BYOFFSET;

	m_lpdijoy->SetProperty(DIPROP_RANGE,&joy_axis_range.diph);


	// and now the dead band
	DIPROPDWORD dead_band; // here's our property word

	// scale dead zone by 100
	dead_zone*=100;

	dead_band.diph.dwSize       = sizeof(dead_band);
	dead_band.diph.dwHeaderSize = sizeof(dead_band.diph);
	dead_band.diph.dwObj        = DIJOFS_X;
	dead_band.diph.dwHow        = DIPH_BYOFFSET;

	// deadband will be used on both sides of the range +/-
	dead_band.dwData            = dead_zone;

	// finally set the property
	m_lpdijoy->SetProperty(DIPROP_DEADZONE,&dead_band.diph);

	dead_band.diph.dwSize       = sizeof(dead_band);
	dead_band.diph.dwHeaderSize = sizeof(dead_band.diph);
	dead_band.diph.dwObj        = DIJOFS_Y;
	dead_band.diph.dwHow        = DIPH_BYOFFSET;

	// deadband will be used on both sides of the range +/-
	dead_band.dwData            = dead_zone;


	// finally set the property
	m_lpdijoy->SetProperty(DIPROP_DEADZONE,&dead_band.diph);

	// acquire the joystick
	if (m_lpdijoy->Acquire()!=DI_OK)
		return -1;

	// set found flag
	m_joystick_found = 1;

	// return success
	return 0;

} // end Init_Joystick


int CGameInput::Init_Mouse()
{
	// this function intializes the mouse

	// create a mouse device 
	if (m_lpdi->CreateDevice(GUID_SysMouse, &m_lpdimouse, NULL)!=DI_OK)
		return -1;

	// set cooperation level
	// change to EXCLUSIVE FORGROUND for better control
	if (m_lpdimouse->SetCooperativeLevel(m_hWnd, 
		DISCL_NONEXCLUSIVE | DISCL_BACKGROUND)!=DI_OK)
		return -1;

	// set data format
	if (m_lpdimouse->SetDataFormat(&c_dfDIMouse)!=DI_OK)
		return -1;

	// acquire the mouse
	if (m_lpdimouse->Acquire()!=DI_OK)
		return -1;

	// return success
	return 0;

} // end DInput_Init_Mouse

int CGameInput::Read_Joystick()
{
	// this function reads the joystick state

	// make sure the joystick was initialized
	if (!m_joystick_found)
		return -1;

	if (m_lpdijoy)
	{
		// this is needed for joysticks only    
		if (m_lpdijoy->Poll()!=DI_OK)
			return -1;

		if (m_lpdijoy->GetDeviceState(sizeof(DIJOYSTATE), (LPVOID)&m_joy_state)!=DI_OK)
			return(0);
	}
	else
	{
		// joystick isn't plugged in, zero out state
		memset(&m_joy_state,0,sizeof(m_joy_state));

		// return error
		return -1;
	} // end else

	// return sucess
	return 0;

} // end Read_Joystick

///////////////////////////////////////////////////////////

int CGameInput::Read_Mouse()
{
	// this function reads  the mouse state

	if (m_lpdimouse)    
	{
		if (m_lpdimouse->GetDeviceState(sizeof(DIMOUSESTATE), (LPVOID)&m_mouse_state)!=DI_OK)
			return -1;
	}
	else
	{
		// mouse isn't plugged in, zero out state
		memset(&m_mouse_state,0,sizeof(m_mouse_state));

		// return error
		return -1;
	} // end else

	// return sucess
	return 0;

} // end Read_Mouse

///////////////////////////////////////////////////////////

int CGameInput::Read_Keyboard()
{
	// this function reads the state of the keyboard

	if (m_lpdikey)
	{
		if (m_lpdikey->GetDeviceState(256, (LPVOID)m_keyboard_state)!=DI_OK)
			return -1;
	}
	else
	{
		// keyboard isn't plugged in, zero out state
		memset(m_keyboard_state,0,sizeof(m_keyboard_state));

		// return error
		return -1;
	} // end else

	// return sucess
	return 0;

} // end Read_Keyboard

int CGameInput::Release_Joystick()
{
	// this function unacquires and releases the joystick

	if (m_lpdijoy)
	{    
		m_lpdijoy->Unacquire();
		m_lpdijoy->Release();
		m_lpdijoy = NULL;
	} // end if

	return 0;

} // end DInput_Release_Joystick

///////////////////////////////////////////////////////////

int CGameInput::Release_Mouse()
{
	// this function unacquires and releases the mouse

	if (m_lpdimouse)
	{    
		m_lpdimouse->Unacquire();
		m_lpdimouse->Release();
		m_lpdimouse = NULL;
	} // end if

	return 0;

} // end DInput_Release_Mouse

///////////////////////////////////////////////////////////

int CGameInput::Release_Keyboard()
{
	// this function unacquires and releases the keyboard

	if (m_lpdikey)
	{
		m_lpdikey->Unacquire();
		m_lpdikey->Release();
		m_lpdikey = NULL;
	} // end if

	return 0;

} // end DInput_Release_Keyboard

int CGameInput::Shutdown()
{
// this function shuts down directinput

	Release_Joystick();
	Release_Mouse();
	Release_Keyboard();

	if (m_lpdi)
	{
		m_lpdi->Release();
		m_lpdi = NULL;
	}

	return 0;

} // end DInput_Shutdown